﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.UI;
using Microsoft.EntityFrameworkCore;
using Partner.Surround.Authorization;
using Partner.Surround.Core.DataDictionaries.DataDictionaryItems.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Partner.Surround.Core.DataDictionaries.DataDictionaryItems
{
    public class DataDictionaryItemAppService : SurroundAppServiceBase, IDataDictionaryItemAppService
    {
        #region 初始化
        private readonly IRepository<DataDictionary, long> _dataDictionaryRepository;
        private readonly IRepository<DataDictionaryItem, long> _dataDictionaryItemRepository;

        public DataDictionaryItemAppService(IRepository<DataDictionary, long> dataDictionaryRepository,
            IRepository<DataDictionaryItem, long> dataDictionaryItemRepository)
        {
            _dataDictionaryRepository = dataDictionaryRepository;
            _dataDictionaryItemRepository = dataDictionaryItemRepository;
        }
        #endregion

        public async Task<DataDictionaryItemEditDto> GetDataDictionaryItemForEditAsync(NullableIdDto<long> input)
        {
            var dataDictionaryItemEditDto = new DataDictionaryItemEditDto();

            if (input.Id.HasValue)
            {
                var dataDictionaryItem = await _dataDictionaryItemRepository.GetAsync(input.Id.Value);
                dataDictionaryItemEditDto = ObjectMapper.Map<DataDictionaryItemEditDto>(dataDictionaryItem);
            }

            return dataDictionaryItemEditDto;
        }

        public async Task CreateOrUpdateDataDictionaryItemAsync(CreateOrUpdateDataDictionaryItemInput input)
        {
            if (input.DataDictionaryItem.Id.HasValue)
                await UpdateDataDictionaryItem(input);
            else
                await CreateDataDictionaryItem(input);
        }

        [AbpAuthorize(PermissionNames.Pages_Core_DataDictionaryItem_Create)]
        private async Task CreateDataDictionaryItem(CreateOrUpdateDataDictionaryItemInput input)
        {
            var existedDataDictionaryItem = await _dataDictionaryItemRepository.GetAll()
                .Where(d => d.DataDictionaryId == input.DataDictionaryItem.DataDictionaryId)
                .Where(d => d.Name == input.DataDictionaryItem.Name).FirstOrDefaultAsync();

            if (existedDataDictionaryItem != null)
            {
                throw new UserFriendlyException(L("该字典名称已存在，无法添加"));
            }

            var dataDictionaryItem = ObjectMapper.Map<DataDictionaryItem>(input.DataDictionaryItem);

            await _dataDictionaryItemRepository.InsertAsync(dataDictionaryItem);
        }

        [AbpAuthorize(PermissionNames.Pages_Core_DataDictionaryItem_Edit)]
        private async Task UpdateDataDictionaryItem(CreateOrUpdateDataDictionaryItemInput input)
        {
            if (!input.DataDictionaryItem.Id.HasValue || input.DataDictionaryItem.Id.Value <= 0)
            {
                throw new UserFriendlyException(L("操作异常，数据有误"));
            }

            var dataDictionaryItem = await _dataDictionaryItemRepository.GetAsync(input.DataDictionaryItem.Id.Value);

            var isExistedDataDictionaryItem = await _dataDictionaryItemRepository.GetAll().Where(d => d.DataDictionaryId == dataDictionaryItem.DataDictionaryId && d.Name == input.DataDictionaryItem.Name && d.Id != dataDictionaryItem.Id).AnyAsync();
            if (isExistedDataDictionaryItem)
            {
                throw new UserFriendlyException(L("该字典名称已存在，无法更新"));
            }

            ObjectMapper.Map(input.DataDictionaryItem, dataDictionaryItem);

            await _dataDictionaryItemRepository.UpdateAsync(dataDictionaryItem);
        }

        public async Task DeleteDataDictionaryItemAsync(List<EntityDto<long>> inputs)
        {
            foreach (var input in inputs)
            {
                await _dataDictionaryItemRepository.DeleteAsync(input.Id);
            }
        }

        public async Task<GetDataDictionaryItemNameOutput> GetDataDictionaryItemNameAsync(GetDataDictionaryItemNameInput input)
        {
            var dataDictionary = await _dataDictionaryRepository.GetAll()
                .Where(d => d.TypeName == input.TypeName)
                .FirstOrDefaultAsync();

            if (dataDictionary == null)
            {
                throw new UserFriendlyException(string.Format("指定字典类型不存在:{0}", input.TypeName));
            }

            var dataDictionaryItem = await _dataDictionaryItemRepository.GetAll()
                .Where(di => di.DataDictionaryId == dataDictionary.Id && di.Code == input.ItemCode)
                .FirstOrDefaultAsync();

            return new GetDataDictionaryItemNameOutput()
            {
                ItemName = dataDictionaryItem == null ? "" : dataDictionaryItem.Name
            };
        }

        public async Task<ListResultDto<DataDictionaryItemListDto>> GetDataDictionaryItemListAsync(GetDataDictionaryItemListInput input)
        {
            var items = await _dataDictionaryItemRepository.GetAll()
                .Where(di => di.DataDictionaryId == input.DataDictionaryId)
                .ToListAsync();

            return new ListResultDto<DataDictionaryItemListDto>(items.Select(item =>
            {
                return ObjectMapper.Map<DataDictionaryItemListDto>(item);
            }).ToList());
        }
    }
}
